package com.cicdi.jcli.util;

import com.alaya.crypto.*;
import com.cicdi.jcli.model.WalletFileX;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.math.BigInteger;
import java.security.SecureRandom;

import static com.alaya.crypto.Hash.sha256;

/**
 * 钱包工具
 *
 * @author haypo
 * @date 2021/3/1
 */
@Slf4j
public class WalletUtil {
    private static final SecureRandom secureRandom = SecureRandomUtils.secureRandom();

    static {
        if (SecureRandomUtils.isAndroidRuntime()) {
            new LinuxSecureRandom();
        }
    }

    /**
     * 创建钱包文件
     *
     * @param password 密码
     * @param file     钱包路径
     * @return 是否创建成功
     */
    public static boolean createWalletFile(String password, File file, String hrp) {
        try {
            WalletFileX wfx = generateBip39Wallet(password, file, hrp);
            log.info("已创建钱包文件：{} 地址：{}", wfx.getFilename(), wfx.getAddress());
            File dir = new File("wallet");
            if (dir.mkdirs()) {
                System.out.println("已创建wallet文件夹");
            }
            String wfxFilename = dir.getName() + "/Bip39-" + wfx.getFilename();
            String finalFilename = JsonUtil.writeJsonFileWithNoConflict(wfxFilename, wfx);
            log.info("已创建助记词密文文件：{}", finalFilename);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    public static WalletFile genWalletByPrivateKey(String privateKey, String password) throws CipherException {
        ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
        return Wallet.createStandard(password, ecKeyPair);
    }

    public static WalletFile genWalletByMnemonic(String mnemonic, String password) throws CipherException {
        byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
        ECKeyPair ecKeyPair = ECKeyPair.create(sha256(seed));
        return Wallet.createStandard(password, ecKeyPair);
    }

    public static WalletFile genWalletFile(String password, String hrp) throws CipherException {
        byte[] initialEntropy = new byte[16];
        secureRandom.nextBytes(initialEntropy);

        String mnemonic = MnemonicUtils.generateMnemonic(initialEntropy);
        byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
        ECKeyPair ecKeyPair = ECKeyPair.create(sha256(seed));

        return Wallet.createStandard(password, ecKeyPair);
    }

    private static WalletFileX generateBip39Wallet(String password, File file, String hrp) throws Exception {
        byte[] initialEntropy = new byte[16];
        secureRandom.nextBytes(initialEntropy);

        String mnemonic = MnemonicUtils.generateMnemonic(initialEntropy);
        byte[] seed = MnemonicUtils.generateSeed(mnemonic, password);
        ECKeyPair ecKeyPair = ECKeyPair.create(sha256(seed));

        WalletFile walletFile = Wallet.createStandard(password, ecKeyPair);

        String finalFilename = JsonUtil.writeJsonFileWithNoConflict(file.getName(), walletFile);
        return new WalletFileX(
                walletFile.getAddress().getMainnet(),
                finalFilename,
                AesUtil.getAesUtil().encrypt(mnemonic, password),
                hrp
        );
    }
}
